import { Modal } from 'antd';
import { useContext, useRef, forwardRef, useImperativeHandle } from 'react';
import { useMemoizedFn, useSafeState } from 'ahooks';
import Context from '../context';
import Girds from '../Grids';
import Seats from '../Seats';
import MouseContrl from '../MouseContrl';
import { ActionEnums } from '../Actions/enum';
import EditMoveSeat from '../EditMoveSeat';
import EditSeatNumber, { type SeatNumberValues } from '../EditSeatNumber';
import type { GridType, SeatType } from '../types';
import type { MoveSeatOpts } from './types';

import {
  delSeats,
  moveSeats,
  seatsNumber,
  checkSeatNum,
  delSeatNumber,
  createSeats,
  getSelectedSeats,
} from './helper';

import { getSeat } from '../helper';

import styles from './styles.module.less';

export type CanvasRefs = {
  getDelDeats: () => SeatType[];
}

const Canvas = forwardRef<CanvasRefs>((_, ref) => {
  const {
    mode,
    cols,
    rows,
    seats,
    seatSize,
    setSeats,
    selectedSeats,
    setSelectedSeats
  } = useContext(Context);

  // 被删除的座位
  const scrapSeats = useRef<Record<string, string>>({});
  const [openMoveSeat, setOpenMoveSeat] = useSafeState(false);
  const [openSeatNumber, setOpenSeatNumber] = useSafeState(false);

  const closeMoveSeat = useMemoizedFn(() => setOpenMoveSeat(false));

  const getDelDeats = useMemoizedFn(() => {
    const s = scrapSeats.current;
    return Object.values(s).map(getSeat);
  });

  // 移动座位
  const handleMoveSeats = useMemoizedFn((options: MoveSeatOpts) => {
    const { row, column } = options;
    if (!row.step && !column.step) {
      closeMoveSeat();
      return;
    }

    const result = moveSeats(seats, {
      ...options,
      selectedSeats,
      maxRow: rows,
      maxColumn: cols,
    });

    if (result !== false) {
      setSeats(result);
      closeMoveSeat();
    };
  });

  // 座位编号
  const handleSeatNumber = useMemoizedFn((values: SeatNumberValues) => {
    const res = seatsNumber(seats, {
      ...values,
      selectedSeats
    });
    setSeats(res);
    setOpenSeatNumber(false);
  });

  // 删除座位编号
  const handleDelSeatNumber = useMemoizedFn(() => {
    setSeats(delSeatNumber(seats, selectedSeats));
  });

  // 删除座位
  const handleDelSeats = useMemoizedFn(() => {
    setSeats(delSeats({
      seats,
      selectedSeats,
      scrapSeats: scrapSeats.current
    }));
  });

  const handleSelected = useMemoizedFn((grids: GridType[]) => {
    // 画座位
    if (mode === ActionEnums.DRAW_SEAT) {
      const _seats = createSeats({
        seats,
        grids,
        scrapSeats: scrapSeats.current
      });
      if (_seats) setSeats(_seats);
      return;
    }

    const selectedSeats = getSelectedSeats(seats, grids);
    const count = Object.values(selectedSeats).length;

    if (!count) {
      return;
    }

    setSelectedSeats(selectedSeats);

    switch (mode) {
      case ActionEnums.MOVE_SEAT: {
        setOpenMoveSeat(true);
        break;
      }
      case ActionEnums.SEAT_NUM: {
        setOpenSeatNumber(true);
        break;
      }
      case ActionEnums.STATISTICS_SEAT: {
        Modal.info({
          title: '座位统计',
          okText: '知道啦',
          content: `当前选中的座位数为：${count}`
        });
        break;
      }
      case ActionEnums.DELETE_SEAT: {
        if (!checkSeatNum(selectedSeats)) {
          Modal.confirm({
            title: '删除座位',
            okText: '删除座位',
            cancelText: '取消',
            okType: 'danger',
            onOk: handleDelSeats,
            content: '确定要删除座位吗？'
          });
        } else {
          Modal.confirm({
            title: '删除编号',
            okText: '删除编号',
            cancelText: '取消',
            okType: 'danger',
            onOk: handleDelSeatNumber,
            content: '选中的座位中存在已编号的座位，是否删除编号？'
          });
        }
        break;
      }
    }
  });

  useImperativeHandle(ref, () => ({ getDelDeats }));

  return (
    <div className={styles.canvas}>
      <Girds
        unit={5}
        cols={cols}
        rows={rows}
        cellSize={seatSize}
      />
      <Seats
        cols={cols}
        rows={rows}
        seats={seats}
        seatSize={seatSize}
      />
      <MouseContrl
        cols={cols}
        rows={rows}
        seatSize={seatSize}
        onSelected={handleSelected}
      />
      <EditMoveSeat
        open={openMoveSeat}
        onClose={closeMoveSeat}
        onSubmit={handleMoveSeats}
      />
      <EditSeatNumber
        open={openSeatNumber}
        onSubmit={handleSeatNumber}
        onDelete={handleDelSeatNumber}
        onClose={() => setOpenSeatNumber(false)}
      />
    </div>
  );
});

export default Canvas;